AN INTRODUCTION TO VIEWFRAME
Jason Harper
76703.4222@compuserve.com

THIS ARTICLE WAS FIRST PUBLISHED IN PDA DEVELOPERS (FORMERLY PIE DEVELOPERS)
MAGAZINE. COPYRIGHT (C) 1994 BY CREATIVE DIGITAL SYSTEMS. ALL RIGHTS RESERVED.
CONTACT CREATIVE DIGITAL SYSTEMS AT CDS@NETCOM.COM FOR MORE INFORMATION. 

The debugging tools available for the Newton platform have been rather
limited to date. Here are some of my experiences with the available tools,
along with a description of my efforts to improve the situation.

THE INSPECTOR
The NTK (Newton ToolKit) has a built-in NewtonScript object examination tool
called the Inspector. It runs on a host computer (currently, only a
Macintosh) tethered to the Newton device being examined. This gives it the
distinct advantage over any Newton-based tool of not being limited in its
displays to the rather small screen size of current Newton devices. 
		However, it has some major limitations in the information it shows
about the objects it displays, and in the options available for further
displaying and modifying these objects. As an example, let's look at the
output the Inspector might produce when we examine the _proto slot of an
unidentified view:

#28F	{_proto: {#31B}, 
		viewBounds: {#2963E5}, 
		viewJustify: 166, 
		icon: {#4DF}, 
		buttonClickScript: <CodeBlock, 0 args #296405>}

What is this? From the fact that the frame has both an icon and a
buttonClickScript slot, you might deduce that this is a protoPictureButton,
or some variation thereof. Looking at the object's prototype might confirm or
deny this. To do so, you have to retype the reference number of the _proto
slot, in the form ref(0x31b). [According to DTS, Ref is an unreliable
function that will be "going away soon." They advise against its use. Ed]. In
this case, the prototype contains a debug slot with the value
"protoPictureButton" (many of the system proto templates have a debug slot,
so you can find out the basic type of many views if you follow their _proto
chain far enough). 
		However, it is not always possible to examine frame slots in the
Inspector. There are two reasons why your peek might fail:

*	The reference may no longer be valid. The NewtonScript garbage collector
may have reclaimed or relocated the object. The garbage collector can hardly
be expected to notice that there is still a reference to the object, on the
screen of another computer.
*	It may be impossible to reenter the reference value. NewtonScript
integers are limited to 30 bits, but references are full 32-bit values. If
either of the highest two bits of a reference are set, there is no way to
directly enter it. You have to use a workaround such as specifying a
different path to the desired slot, such as ref(0x28f)._proto in the current
example.

		We've identified the object as a picture button, but what button is
it? Looking at its icon might tell, so let's do so:

#4DF	{mask: <mask, length 52>, 
		bits: <bits, length 52>, 
		bounds: {#235F55}}

This is, unfortunately, about as far as the Inspector can go. You can look at
the bounds slot to find that the icon is 9 by 9 pixels, but the Inspector has
no capability for showing any meaningful representation of the mask and bits
slots, or any other binary objects that don't have a defined textual version.
You can get a little more information by going back to the object's
buttonClickScript - typing in ref(0x296405).literals reveals that the script
uses the symbols base and Close. Perhaps the script is base:Close()? There's
no way to tell for sure.

OBJVIEWER
It wasn't very long after the Newton introduction that a stand-alone
NewtonScript object examining tool appeared - ObjViewer, a freeware program
by Robert P. Munafo which was discussed in the last issue of PIE Developers.
It has a movable window, half the height of current Newton screens, so you
can always see what else is going on. It displays ten lines at a time of
frames, arrays, binary objects (shown in hexadecimal) and other data types.
Viewing an object referenced by a frame or array slot is as simple as tapping
on the line describing it - there is no chance of failure as with the
Inspector. 
		For comparison, here is our example frame as displayed by ObjViewer:

Frame!0000028F;0/5 slots            
_proto: {..8..}
viewBounds: {..4..}
viewJustify: 166
icon: {..3..}
buttonClickScript: {..5..}CodeBlock

Note that frames are displayed with the number of slots they contain,
generally a far more useful piece of data than the reference number shown in
the Inspector. The icon object can be viewed more easily than before, and we
can even look at its data bits:

bits!00235FB6;52 bytes                  
	0:	00000000000401C5|        
	8:	01C5025E01CE0267|   ^   g
	16:	C1800000E3800000|        
	24:	770000003E000000|w   >   
	32:	1C0000003E000000|    >   
	40:	77000000E3800000|w       
	48:	C1800000                |        

Unfortunately, this still doesn't tell us what the view actually is, unless
you're a lot better at visualizing binary data than I am.
		A major deficiency of ObjViewer is that it can only examine objects
reachable from the root view, as returned by the GetRoot() global function.
This is the root of the view system only, not of the entire Newton object
system. There are many items of interest that can't be reached from
GetRoot(), or that don't exist as objects at all until a program requests
them (such as soup entries). Also, ObjViewer is a purely read-only tool.
Sometimes it is more convenient to test a small program change directly in
the Newton memory rather than taking the time to recompile the whole program.

INSPECTOR GADGET
Another tool that developers may find useful, which may seem unrelated to
object viewing at first glance, is a way to test fragments of NewtonScript
code without the time and trouble required to set up a complete program in
the NTK. The Inspector can be used for this purpose, although it can be
somewhat tricky: some NewtonScript constructs don't work directly from the
Inspector - they have to be enclosed in a function which is then called.
Also, the Inspector isn't always available. 
		What if you are miles away from your Mac, and are suddenly just dying
to know what happens if you remove a slot from a frame you're currently
looping through with a foreach statement? Apple supplies a simple
NewtonScript experimentation tool named Inspector Gadget. It's one of the
sample programs included with the NTK. A variation on this program has been
distributed by Howard Oakley under the name NewtonScript Runner. While these
tools can be useful (I did a lot of the early work that led to ViewFrame
using Inspector Gadget, since I didn't have a Macintosh of my own at the
time), they are rather clumsy to use, due to the difficulty of entering
NewtonScript expressions directly on a Newton device. 
		Handwritten input is impractical - several important NewtonScript
punctuation marks, such as curly and square brackets, are not recognized no
matter how clearly you write them. The on-screen keyboard works, but it's
constantly asking you if you want to add useless words to your personal
dictionary, and it's rather slow to use. Tap in "viewSetupFormScript" a few
times, and you know what I mean. 
		But perhaps the main problem with these utilities is their limitation
in displaying the results from code you entered. Both just turn the result
into a string with the SPrintObject() function, which returns an empty string
for many objects. All frames and arrays, as well as some simpler objects such
as NIL and TRUE simply come out blank. It's possible to enter a foreach loop
that turns frames and arrays into meaningful strings which can be returned,
but this routine takes up much of the input area provided by these tools,
leaving little room for anything for the routine to operate on.

VIEWFRAME
Faced with a desire to learn more about how my Newton MessagePad works than
was documented, and a lack of really good tools to do so, I decided to write
my own object browsing utility. I wanted something that could meaningfully
display any NewtonScript object, and had no limitations on what objects could
be viewed. This program, which ended up being called ViewFrame, is obviously
going to be a work-in-progress for as long as Apple continues to refine the
Newton system. But even in its first version it is quite capable of showing
you more of what's going on "under the hood" than any existing tool. 
		Figure 1 below shows how ViewFrame displays the unidentified frame of
the earlier examples:

*	Note that the debug slot's value ("protoPictureButton") from the
object's prototype is shown in the listing for the _proto slot, saving you
the effort of opening that slot to see what it is.
*	Notice the @nnn notations that appear in several places. These are magic
pointers, an important NewtonScript construct that is unfortunately discussed
only briefly in current documentation. By looking them up in the NTK
Definitions file you can tell exactly what the referenced object is. In this
case the _proto is an object named protoPictureButton (already identified by
the debug slot), and the icon is named ROM_cancelbitmap. The object itself is
finally identified as the protoCancelButton. 
		Hint: you can identify magic pointers using other debugging tools,
too. Subtract three from an object's reference value, then divide by four. If
the result is an integer, that's the magic pointer number for the object.
This is probably not guaranteed to remain true for future Newton devices, but
it's a quite useful trick for now. [There is also a function called
IsMagicPtr. Ed].

		Figure 2 shows more examples of ViewFrame's object displays, from
slots in the protoCancelButton frame. Icons and pictures are displayed in
graphical form, and currently eight common types of flags fields can be
displayed as symbolic constants. Even NewtonScript functions can be displayed
as an approximation of the original source code, although the results aren't
always as accurate as in the example (the current version of ViewFrame can't
fully interpret looping and conditional constructs).

OTHER FEATURES
ViewFrame has quite a few other features:

*	In addition to the object types shown in the examples, there are
specific view formats for sounds (which are played), soup entries, strings
and other types. Many object types have an alternate view format. For
example, the icon above can be viewed as its component binary objects, if you
really want to see that information
*	ViewFrame's window is fully resizeable, so you can have it take up the
whole screen if you don't need to see anything else at the same time. If the
full screen isn't enough area, you can dump the output to the Inspector if
it's connected.
*	The contents of Newton dictionaries (other than lexical dictionaries,
such as the phone numbers recognizer) can be dumped to the Inspector.
*	You can navigate the Newton object hierarchy by either tapping on slots
or entering expressions at the top of the window. Tapping the diamond in the
upper lefthand corner of the ViewFrame window brings up a list of expressions
you can use, including common places to start browsing such as GetRoot() and
GetGlobals(), and expressions relevant to the current object such as
:ChildViewFrames(), when the object is an open view. Almost any NewtonScript
operation can be executed using ViewFrame by entering the proper expressions.
For example, by using the functions GetStores(), :GetSoup(), Query(),
:Entry() and :Next() , all of which appear in the expression list at the
appropriate time, you can examine the contents of any soup.
*	Programs that you write can call ViewFrame directly to display an
arbitrary object, using a statement such as: 

	GetRoot().|ViewFrame:JRH|:?NewValue(
		description, object);

	It's hardly as convenient as using a simple print() statement to send
output to the Inspector, but can be used at times when the Inspector is
unusable (such as while debugging a program that uses serial I/O).

ACCESSORIES
In order to make it easy to experiment with NewtonScript code, I wrote a
companion program called the ViewFrame Editor (see Figure 3). It looks and
acts much like the Newton Notepad, except that drawn shapes are not allowed.
The returned value from programs you enter can be displayed using ViewFrame,
so you don't have to worry about formatting the return value in a
human-readable form. The Editor supports scrolling, so program size is
limited only by available memory.
		In order to make NewtonScript entry practical in the ViewFrame Editor
and the expression entry area of ViewFrame itself, I also created a
Programmer's Keyboard (shown in Figure 3). It works the same as the standard
on-screen keyboard (except that entry of words into your personal dictionary
isn't supported), but also has several common NewtonScript phrases and
punctuation marks available for entry with a single tap. For example,
"viewSetupFormScript" can be typed in with only seven taps: "view", "Setup"
and "Script" require only one tap each. As an added bonus, the Keyboard can
be switched to a Dvorak layout for those of you who are more comfortable with
that.

AVAILBILITY
As I mentioned, ViewFrame is a work in progress. By the time you read this,
current owners should have already received a free editor upgrade. In
addition, there are a variety of new features that I'm working on. Judging by
the response from the Newton developer community, it's a very useful utility.

---
Jason Harper is a freelance Apple II programmer who still, somehow, has
enough faith in Apple to give Newton development a try.  His other Newton
programs include ExtraExtras, an Extras Drawer extender, and BeamToSelf, for
testing beaming with only a single Newton device.
---
ViewFrame is available exclusively from Creative Digital Systems. See the
inside back cover of this issue for details. A demo version of ViewFrame is
available on most major bulletin board systems and on the PIE Developers 2.2
source code disk.

